Micron Document
🎖️GitЯра🎖️

Commit 1390a3cd4f7bc55a37433d1d868e65c01678eb31


Parents : 93e0b9c
Author : James Rich <2199651+jamesarich@users.noreply.github.com>
Signature : Signature validation error
Date : 2026-04-10T10:05:07-05:00
Committer : GitHub <noreply@github.com>
Date : 2026-04-10T10:05:07-05:00

ci: cache Robolectric SDK jars to prevent flaky SocketException failures (#5045)

Changes

34 files changed, 374 insertions(+), 426 deletions(-)

M AGENTS.md +2 -1

Diff

diff --git a/.github/actions/gradle-setup/action.yml b/.github/actions/gradle-setup/action.yml
index 8caf40c787..89dda74115 100644
--- a/.github/actions/gradle-setup/action.yml
+++ b/.github/actions/gradle-setup/action.yml
@@ -27,6 +27,15 @@ runs:
distribution: ${{ inputs.jdk_distribution }}
token: ${{ github.token }}
+ # Robolectric downloads instrumented SDK jars from Maven Central at test time.
+ # Cache them to avoid flaky SocketException failures on CI runners.
+ # Update the key when bumping robolectric version in libs.versions.toml or sdk in robolectric.properties.
+ - name: Cache Robolectric SDK jars
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2/repository/org/robolectric
+ key: robolectric-4.16.1-sdk34
+
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v6
with:

diff --git a/AGENTS.md b/AGENTS.md
index 40adbfd06f..b5aa22fb77 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -41,7 +41,7 @@ Meshtastic-Android is a Kotlin Multiplatform (KMP) application for off-grid, dec
| `core:data` | Core manager implementations and data orchestration. |
| `core:network` | KMP networking layer using Ktor, MQTT abstractions, and shared transport (`StreamFrameCodec`, `TcpTransport`, `SerialTransport`, `BleRadioInterface`). |
| `core:di` | Common DI qualifiers and dispatchers. |
-| `core:navigation` | Shared navigation keys/routes for Navigation 3, `DeepLinkRouter` for typed backstack synthesis, and `MeshtasticNavSavedStateConfig` for backstack persistence. |
+| `core:navigation` | Shared navigation keys/routes for Navigation 3 using `@Serializable sealed interface` hierarchies per feature domain (e.g., `SettingsRoute`, `NodesRoute`). `DeepLinkRouter` for typed backstack synthesis, and `MeshtasticNavSavedStateConfig` with `subclassesOfSealed()` for automatic polymorphic backstack persistence — new routes are registered at compile time. |
| `core:ui` | Shared Compose UI components (`MeshtasticAppShell`, `MeshtasticNavDisplay`, `MeshtasticNavigationSuite`, `AlertHost`, `SharedDialogs`, `PlaceholderScreen`, `MainAppBar`, dialogs, preferences) and platform abstractions. |
| `core:service` | KMP service layer; Android bindings stay in `androidMain`. |
| `core:api` | Public AIDL/API integration module for external clients. |
@@ -189,6 +189,7 @@ Always run commands in the following order to ensure reliability. Do not attempt
- **`maxParallelForks` CI logic:** ProjectExtensions.kt line ~79 checks `project.findProperty("ci") == "true"` and uses full available processors in CI (4 forks on std runners) vs. half locally. All CI invocations pass `-Pci=true` to enable this.
- **Detekt report formats:** Detekt.kt line ~44 checks `project.findProperty("ci") == "true"` and disables html, txt, md reports in CI; only xml + sarif are required for GitHub reporting.
- **KMP Smoke Compile:** Use `./gradlew kmpSmokeCompile` instead of listing individual module compile tasks. The `kmpSmokeCompile` lifecycle task (registered in `RootConventionPlugin`) auto-discovers all KMP modules and depends on their `compileKotlinJvm` + `compileKotlinIosSimulatorArm64` tasks.
+- **Robolectric SDK caching:** The `gradle-setup` composite action caches `~/.m2/repository/org/robolectric` to prevent flaky `SocketException` failures when Robolectric downloads instrumented SDK jars. The cache key is `robolectric-{version}-sdk{level}` — update it when bumping the Robolectric version in `libs.versions.toml` or the SDK level in `robolectric.properties` / `@Config(sdk = ...)`.
- **`mavenLocal()` gated:** The `mavenLocal()` repository is disabled by default to prevent CI cache poisoning. For local JitPack testing, pass `-PuseMavenLocal` to Gradle.
- **Terminal Pagers:** When running shell commands like `git diff` or `git log`, ALWAYS use `--no-pager` (e.g., `git --no-pager diff`) to prevent the agent from getting stuck in an interactive prompt.
- **Text Search:** Prefer using `rg` (ripgrep) over `grep` or `find` for fast text searching across the codebase.

diff --git a/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt b/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt
index 19c6c9ddf0..1e5b68ab02 100644
--- a/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt
+++ b/app/src/main/kotlin/org/meshtastic/app/ui/Main.kt
@@ -32,7 +32,7 @@ import co.touchlab.kermit.Logger
import org.koin.compose.viewmodel.koinViewModel
import org.meshtastic.app.BuildConfig
import org.meshtastic.core.model.ConnectionState
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.navigation.rememberMultiBackstack
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.app_too_old
@@ -53,7 +53,7 @@ import org.meshtastic.feature.wifiprovision.navigation.wifiProvisionGraph
@Composable
fun MainScreen() {
val viewModel: UIViewModel = koinViewModel()
- val multiBackstack = rememberMultiBackstack(NodesRoutes.NodesGraph)
+ val multiBackstack = rememberMultiBackstack(NodesRoute.NodesGraph)
val backStack = multiBackstack.activeBackStack
AndroidAppVersionCheck(viewModel)

diff --git a/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt b/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt
index ac082ffa35..ef4dab3e69 100644
--- a/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt
+++ b/app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt
@@ -24,7 +24,7 @@ import kotlinx.coroutines.flow.emptyFlow
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.feature.connections.navigation.connectionsGraph
import org.meshtastic.feature.firmware.navigation.firmwareGraph
import org.meshtastic.feature.map.navigation.mapGraph
@@ -44,7 +44,7 @@ class NavigationAssemblyTest {
@Test
fun verifyNavigationGraphsAssembleWithoutCrashing() {
composeTestRule.setContent {
- val backStack = rememberNavBackStack(NodesRoutes.NodesGraph)
+ val backStack = rememberNavBackStack(NodesRoute.NodesGraph)
entryProvider<NavKey> {
contactsGraph(backStack, emptyFlow())
nodesGraph(backStack = backStack, scrollToTopEvents = emptyFlow())

diff --git a/core/navigation/README.md b/core/navigation/README.md
index 9927ebf7d0..61e8b00eab 100644
--- a/core/navigation/README.md
+++ b/core/navigation/README.md
@@ -12,7 +12,7 @@ Contains serializable `NavKey` route classes/objects used by shared feature grap
Parses Meshtastic deep-link URIs and synthesizes a typed backstack (for example `/nodes/1234/device-metrics`).
### 3. `NavigationConfig.kt`
-Defines `MeshtasticNavSavedStateConfig` so Navigation 3 backstacks can be persisted/restored safely.
+Defines `MeshtasticNavSavedStateConfig` using sealed interface hierarchies so Navigation 3 backstacks can be persisted/restored safely — new routes are auto-registered at compile time.
## Features
- **Type-Safety**: Uses serializable `NavKey` routes instead of ad-hoc string routes.
@@ -25,10 +25,10 @@ Feature modules depend on this module to define their entry points and navigate
```kotlin
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.NodesRoute
fun openNodeDetail(backStack: NavBackStack<NavKey>, destNum: Int) {
- backStack.add(NodesRoutes.NodeDetail(destNum))
+ backStack.add(NodesRoute.NodeDetail(destNum))
}
```

diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt
index 12f5a911ca..0fdb4d48c2 100644
--- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt
+++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/DeepLinkRouter.kt
@@ -59,11 +59,11 @@ object DeepLinkRouter {
"messages",
"quickchat",
-> routeContacts(uri, pathSegments)
- "connections" -> listOf(ConnectionsRoutes.ConnectionsGraph)
+ "connections" -> listOf(ConnectionsRoute.ConnectionsGraph)
"map" -> routeMap(uri, pathSegments)
"nodes" -> routeNodes(uri, pathSegments)
"settings" -> routeSettings(pathSegments)
- "channels" -> listOf(ChannelsRoutes.ChannelsGraph)
+ "channels" -> listOf(ChannelsRoute.ChannelsGraph)
"firmware" -> routeFirmware(pathSegments)
"wifi-provision" -> routeWifiProvision(uri)
else -> {
@@ -78,31 +78,31 @@ object DeepLinkRouter {
return when (firstSegment) {
"share" -> {
val message = uri.getQueryParameter("message") ?: ""
- listOf(ContactsRoutes.ContactsGraph, ContactsRoutes.Share(message))
+ listOf(ContactsRoute.ContactsGraph, ContactsRoute.Share(message))
}
"quickchat" -> {
- listOf(ContactsRoutes.ContactsGraph, ContactsRoutes.QuickChat)
+ listOf(ContactsRoute.ContactsGraph, ContactsRoute.QuickChat)
}
"messages" -> {
val contactKey = if (segments.size > 1) segments[1] else uri.getQueryParameter("contactKey") ?: ""
val message = uri.getQueryParameter("message") ?: ""
if (contactKey.isNotBlank()) {
listOf(
- ContactsRoutes.ContactsGraph,
- ContactsRoutes.Messages(contactKey = contactKey, message = message),
+ ContactsRoute.ContactsGraph,
+ ContactsRoute.Messages(contactKey = contactKey, message = message),
)
} else {
- listOf(ContactsRoutes.ContactsGraph)
+ listOf(ContactsRoute.ContactsGraph)
}
}
- else -> listOf(ContactsRoutes.ContactsGraph)
+ else -> listOf(ContactsRoute.ContactsGraph)
}
}
private fun routeMap(uri: CommonUri, segments: List<String>): List<NavKey> {
val waypointIdStr = if (segments.size > 1) segments[1] else uri.getQueryParameter("waypointId")
val waypointId = waypointIdStr?.toIntOrNull()
- return listOf(MapRoutes.Map(waypointId))
+ return listOf(MapRoute.Map(waypointId))
}
private fun routeNodes(uri: CommonUri, segments: List<String>): List<NavKey> {
@@ -110,17 +110,17 @@ object DeepLinkRouter {
val destNum = destNumStr?.toIntOrNull()
return if (destNum == null) {
- listOf(NodesRoutes.NodesGraph)
+ listOf(NodesRoute.NodesGraph)
} else if (segments.size > 2) {
val subRouteStr = segments[2].lowercase()
val detailRouteFn = nodeDetailSubRoutes[subRouteStr]
if (detailRouteFn != null) {
- listOf(NodesRoutes.NodesGraph, NodesRoutes.NodeDetailGraph(destNum), detailRouteFn(destNum))
+ listOf(NodesRoute.NodesGraph, NodesRoute.NodeDetailGraph(destNum), detailRouteFn(destNum))
} else {
- listOf(NodesRoutes.NodesGraph, NodesRoutes.NodeDetail(destNum))
+ listOf(NodesRoute.NodesGraph, NodesRoute.NodeDetail(destNum))
}
} else {
- listOf(NodesRoutes.NodesGraph, NodesRoutes.NodeDetail(destNum))
+ listOf(NodesRoute.NodesGraph, NodesRoute.NodeDetail(destNum))
}
}
@@ -142,79 +142,79 @@ object DeepLinkRouter {
}
if (subRouteStr == null) {
- return listOf(SettingsRoutes.SettingsGraph(destNum))
+ return listOf(SettingsRoute.SettingsGraph(destNum))
}
val subRoute = settingsSubRoutes[subRouteStr]
return if (subRoute != null) {
- listOf(SettingsRoutes.SettingsGraph(destNum), subRoute)
+ listOf(SettingsRoute.SettingsGraph(destNum), subRoute)
} else {
- listOf(SettingsRoutes.SettingsGraph(destNum))
+ listOf(SettingsRoute.SettingsGraph(destNum))
}
}
private fun routeWifiProvision(uri: CommonUri): List<NavKey> {
val address = uri.getQueryParameter("address")
- return listOf(WifiProvisionRoutes.WifiProvision(address))
+ return listOf(WifiProvisionRoute.WifiProvision(address))
}
private fun routeFirmware(segments: List<String>): List<NavKey> {
val update = if (segments.size > 1) segments[1].lowercase() == "update" else false
return if (update) {
- listOf(FirmwareRoutes.FirmwareGraph, FirmwareRoutes.FirmwareUpdate)
+ listOf(FirmwareRoute.FirmwareGraph, FirmwareRoute.FirmwareUpdate)
} else {
- listOf(FirmwareRoutes.FirmwareGraph)
+ listOf(FirmwareRoute.FirmwareGraph)
}
}
private val settingsSubRoutes: Map<String, Route> =
mapOf(
- "device-config" to SettingsRoutes.DeviceConfiguration,
- "module-config" to SettingsRoutes.ModuleConfiguration,
- "admin" to SettingsRoutes.Administration,
- "user" to SettingsRoutes.User,
- "channel" to SettingsRoutes.ChannelConfig,
- "device" to SettingsRoutes.Device,
- "position" to SettingsRoutes.Position,
- "power" to SettingsRoutes.Power,
- "network" to SettingsRoutes.Network,
- "display" to SettingsRoutes.Display,
- "lora" to SettingsRoutes.LoRa,
- "bluetooth" to SettingsRoutes.Bluetooth,
- "security" to SettingsRoutes.Security,
- "mqtt" to SettingsRoutes.MQTT,
- "serial" to SettingsRoutes.Serial,
- "ext-notification" to SettingsRoutes.ExtNotification,
- "store-forward" to SettingsRoutes.StoreForward,
- "range-test" to SettingsRoutes.RangeTest,
- "telemetry" to SettingsRoutes.Telemetry,
- "canned-message" to SettingsRoutes.CannedMessage,
- "audio" to SettingsRoutes.Audio,
- "remote-hardware" to SettingsRoutes.RemoteHardware,
- "neighbor-info" to SettingsRoutes.NeighborInfo,
- "ambient-lighting" to SettingsRoutes.AmbientLighting,
- "detection-sensor" to SettingsRoutes.DetectionSensor,
- "paxcounter" to SettingsRoutes.Paxcounter,
- "status-message" to SettingsRoutes.StatusMessage,
- "traffic-management" to SettingsRoutes.TrafficManagement,
- "tak" to SettingsRoutes.TAK,
- "clean-node-db" to SettingsRoutes.CleanNodeDb,
- "debug-panel" to SettingsRoutes.DebugPanel,
- "about" to SettingsRoutes.About,
- "filter-settings" to SettingsRoutes.FilterSettings,
+ "device-config" to SettingsRoute.DeviceConfiguration,
+ "module-config" to SettingsRoute.ModuleConfiguration,
+ "admin" to SettingsRoute.Administration,
+ "user" to SettingsRoute.User,
+ "channel" to SettingsRoute.ChannelConfig,
+ "device" to SettingsRoute.Device,
+ "position" to SettingsRoute.Position,
+ "power" to SettingsRoute.Power,
+ "network" to SettingsRoute.Network,
+ "display" to SettingsRoute.Display,
+ "lora" to SettingsRoute.LoRa,
+ "bluetooth" to SettingsRoute.Bluetooth,
+ "security" to SettingsRoute.Security,
+ "mqtt" to SettingsRoute.MQTT,
+ "serial" to SettingsRoute.Serial,
+ "ext-notification" to SettingsRoute.ExtNotification,
+ "store-forward" to SettingsRoute.StoreForward,
+ "range-test" to SettingsRoute.RangeTest,
+ "telemetry" to SettingsRoute.Telemetry,
+ "canned-message" to SettingsRoute.CannedMessage,
+ "audio" to SettingsRoute.Audio,
+ "remote-hardware" to SettingsRoute.RemoteHardware,
+ "neighbor-info" to SettingsRoute.NeighborInfo,
+ "ambient-lighting" to SettingsRoute.AmbientLighting,
+ "detection-sensor" to SettingsRoute.DetectionSensor,
+ "paxcounter" to SettingsRoute.Paxcounter,
+ "status-message" to SettingsRoute.StatusMessage,
+ "traffic-management" to SettingsRoute.TrafficManagement,
+ "tak" to SettingsRoute.TAK,
+ "clean-node-db" to SettingsRoute.CleanNodeDb,
+ "debug-panel" to SettingsRoute.DebugPanel,
+ "about" to SettingsRoute.About,
+ "filter-settings" to SettingsRoute.FilterSettings,
)
private val nodeDetailSubRoutes: Map<String, (Int) -> Route> =
mapOf(
- "device-metrics" to { destNum -> NodeDetailRoutes.DeviceMetrics(destNum) },
- "map" to { destNum -> NodeDetailRoutes.NodeMap(destNum) },
- "position" to { destNum -> NodeDetailRoutes.PositionLog(destNum) },
- "environment" to { destNum -> NodeDetailRoutes.EnvironmentMetrics(destNum) },
- "signal" to { destNum -> NodeDetailRoutes.SignalMetrics(destNum) },
- "power" to { destNum -> NodeDetailRoutes.PowerMetrics(destNum) },
- "traceroute" to { destNum -> NodeDetailRoutes.TracerouteLog(destNum) },
- "host-metrics" to { destNum -> NodeDetailRoutes.HostMetricsLog(destNum) },
- "pax" to { destNum -> NodeDetailRoutes.PaxMetrics(destNum) },
- "neighbors" to { destNum -> NodeDetailRoutes.NeighborInfoLog(destNum) },
+ "device-metrics" to { destNum -> NodeDetailRoute.DeviceMetrics(destNum) },
+ "map" to { destNum -> NodeDetailRoute.NodeMap(destNum) },
+ "position" to { destNum -> NodeDetailRoute.PositionLog(destNum) },
+ "environment" to { destNum -> NodeDetailRoute.EnvironmentMetrics(destNum) },
+ "signal" to { destNum -> NodeDetailRoute.SignalMetrics(destNum) },
+ "power" to { destNum -> NodeDetailRoute.PowerMetrics(destNum) },
+ "traceroute" to { destNum -> NodeDetailRoute.TracerouteLog(destNum) },
+ "host-metrics" to { destNum -> NodeDetailRoute.HostMetricsLog(destNum) },
+ "pax" to { destNum -> NodeDetailRoute.PaxMetrics(destNum) },
+ "neighbors" to { destNum -> NodeDetailRoute.NeighborInfoLog(destNum) },
)
}

diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt
index fe5c6225a6..f52273f305 100644
--- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt
+++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt
@@ -18,99 +18,28 @@ package org.meshtastic.core.navigation
import androidx.navigation3.runtime.NavKey
import androidx.savedstate.serialization.SavedStateConfiguration
+import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
+import kotlinx.serialization.modules.subclassesOfSealed
/**
- * Shared polymorphic serialization configuration for Navigation 3 saved-state support. Registers all route types used
- * across Android and Desktop navigation graphs.
+ * Shared polymorphic serialization configuration for Navigation 3 saved-state support. Uses sealed interface
+ * hierarchies so that new routes are automatically registered at compile time — no manual `subclass()` calls needed.
*/
+@OptIn(ExperimentalSerializationApi::class)
val MeshtasticNavSavedStateConfig = SavedStateConfiguration {
serializersModule = SerializersModule {
polymorphic(NavKey::class) {
- // Nodes
- subclass(NodesRoutes.NodesGraph::class, NodesRoutes.NodesGraph.serializer())
- subclass(NodesRoutes.Nodes::class, NodesRoutes.Nodes.serializer())
- subclass(NodesRoutes.NodeDetailGraph::class, NodesRoutes.NodeDetailGraph.serializer())
- subclass(NodesRoutes.NodeDetail::class, NodesRoutes.NodeDetail.serializer())
-
- // Node detail sub-screens
- subclass(NodeDetailRoutes.DeviceMetrics::class, NodeDetailRoutes.DeviceMetrics.serializer())
- subclass(NodeDetailRoutes.NodeMap::class, NodeDetailRoutes.NodeMap.serializer())
- subclass(NodeDetailRoutes.PositionLog::class, NodeDetailRoutes.PositionLog.serializer())
- subclass(NodeDetailRoutes.EnvironmentMetrics::class, NodeDetailRoutes.EnvironmentMetrics.serializer())
- subclass(NodeDetailRoutes.SignalMetrics::class, NodeDetailRoutes.SignalMetrics.serializer())
- subclass(NodeDetailRoutes.PowerMetrics::class, NodeDetailRoutes.PowerMetrics.serializer())
- subclass(NodeDetailRoutes.TracerouteLog::class, NodeDetailRoutes.TracerouteLog.serializer())
- subclass(NodeDetailRoutes.TracerouteMap::class, NodeDetailRoutes.TracerouteMap.serializer())
- subclass(NodeDetailRoutes.HostMetricsLog::class, NodeDetailRoutes.HostMetricsLog.serializer())
- subclass(NodeDetailRoutes.PaxMetrics::class, NodeDetailRoutes.PaxMetrics.serializer())
- subclass(NodeDetailRoutes.NeighborInfoLog::class, NodeDetailRoutes.NeighborInfoLog.serializer())
-
- // Conversations
- subclass(ContactsRoutes.ContactsGraph::class, ContactsRoutes.ContactsGraph.serializer())
- subclass(ContactsRoutes.Contacts::class, ContactsRoutes.Contacts.serializer())
- subclass(ContactsRoutes.Messages::class, ContactsRoutes.Messages.serializer())
- subclass(ContactsRoutes.Share::class, ContactsRoutes.Share.serializer())
- subclass(ContactsRoutes.QuickChat::class, ContactsRoutes.QuickChat.serializer())
-
- // Map
- subclass(MapRoutes.Map::class, MapRoutes.Map.serializer())
-
- // Firmware
- subclass(FirmwareRoutes.FirmwareGraph::class, FirmwareRoutes.FirmwareGraph.serializer())
- subclass(FirmwareRoutes.FirmwareUpdate::class, FirmwareRoutes.FirmwareUpdate.serializer())
-
- // Settings
- subclass(SettingsRoutes.SettingsGraph::class, SettingsRoutes.SettingsGraph.serializer())
- subclass(SettingsRoutes.Settings::class, SettingsRoutes.Settings.serializer())
- subclass(SettingsRoutes.DeviceConfiguration::class, SettingsRoutes.DeviceConfiguration.serializer())
- subclass(SettingsRoutes.ModuleConfiguration::class, SettingsRoutes.ModuleConfiguration.serializer())
- subclass(SettingsRoutes.Administration::class, SettingsRoutes.Administration.serializer())
-
- // Settings - Config routes
- subclass(SettingsRoutes.User::class, SettingsRoutes.User.serializer())
- subclass(SettingsRoutes.ChannelConfig::class, SettingsRoutes.ChannelConfig.serializer())
- subclass(SettingsRoutes.Device::class, SettingsRoutes.Device.serializer())
- subclass(SettingsRoutes.Position::class, SettingsRoutes.Position.serializer())
- subclass(SettingsRoutes.Power::class, SettingsRoutes.Power.serializer())
- subclass(SettingsRoutes.Network::class, SettingsRoutes.Network.serializer())
- subclass(SettingsRoutes.Display::class, SettingsRoutes.Display.serializer())
- subclass(SettingsRoutes.LoRa::class, SettingsRoutes.LoRa.serializer())
- subclass(SettingsRoutes.Bluetooth::class, SettingsRoutes.Bluetooth.serializer())
- subclass(SettingsRoutes.Security::class, SettingsRoutes.Security.serializer())
-
- // Settings - Module routes
- subclass(SettingsRoutes.MQTT::class, SettingsRoutes.MQTT.serializer())
- subclass(SettingsRoutes.Serial::class, SettingsRoutes.Serial.serializer())
- subclass(SettingsRoutes.ExtNotification::class, SettingsRoutes.ExtNotification.serializer())
- subclass(SettingsRoutes.StoreForward::class, SettingsRoutes.StoreForward.serializer())
- subclass(SettingsRoutes.RangeTest::class, SettingsRoutes.RangeTest.serializer())
- subclass(SettingsRoutes.Telemetry::class, SettingsRoutes.Telemetry.serializer())
- subclass(SettingsRoutes.CannedMessage::class, SettingsRoutes.CannedMessage.serializer())
- subclass(SettingsRoutes.Audio::class, SettingsRoutes.Audio.serializer())
- subclass(SettingsRoutes.RemoteHardware::class, SettingsRoutes.RemoteHardware.serializer())
- subclass(SettingsRoutes.NeighborInfo::class, SettingsRoutes.NeighborInfo.serializer())
- subclass(SettingsRoutes.AmbientLighting::class, SettingsRoutes.AmbientLighting.serializer())
- subclass(SettingsRoutes.DetectionSensor::class, SettingsRoutes.DetectionSensor.serializer())
- subclass(SettingsRoutes.Paxcounter::class, SettingsRoutes.Paxcounter.serializer())
- subclass(SettingsRoutes.StatusMessage::class, SettingsRoutes.StatusMessage.serializer())
- subclass(SettingsRoutes.TrafficManagement::class, SettingsRoutes.TrafficManagement.serializer())
- subclass(SettingsRoutes.TAK::class, SettingsRoutes.TAK.serializer())
-
- // Settings - Advanced routes
- subclass(SettingsRoutes.CleanNodeDb::class, SettingsRoutes.CleanNodeDb.serializer())
- subclass(SettingsRoutes.DebugPanel::class, SettingsRoutes.DebugPanel.serializer())
- subclass(SettingsRoutes.About::class, SettingsRoutes.About.serializer())
- subclass(SettingsRoutes.FilterSettings::class, SettingsRoutes.FilterSettings.serializer())
-
- // Channels
- subclass(ChannelsRoutes.ChannelsGraph::class, ChannelsRoutes.ChannelsGraph.serializer())
- subclass(ChannelsRoutes.Channels::class, ChannelsRoutes.Channels.serializer())
-
- // Connections
- subclass(ConnectionsRoutes.ConnectionsGraph::class, ConnectionsRoutes.ConnectionsGraph.serializer())
- subclass(ConnectionsRoutes.Connections::class, ConnectionsRoutes.Connections.serializer())
+ subclassesOfSealed<ChannelsRoute>()
+ subclassesOfSealed<ConnectionsRoute>()
+ subclassesOfSealed<ContactsRoute>()
+ subclassesOfSealed<MapRoute>()
+ subclassesOfSealed<NodesRoute>()
+ subclassesOfSealed<NodeDetailRoute>()
+ subclassesOfSealed<SettingsRoute>()
+ subclassesOfSealed<FirmwareRoute>()
+ subclassesOfSealed<WifiProvisionRoute>()
}
}
}

diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt
index b58b20f2b5..b1ccfb4c00 100644
--- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt
+++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt
@@ -25,160 +25,169 @@ interface Route : NavKey
interface Graph : Route
-object ChannelsRoutes {
- @Serializable data object ChannelsGraph : Graph
+@Serializable
+sealed interface ChannelsRoute : Route {
+ @Serializable data object ChannelsGraph : ChannelsRoute, Graph
- @Serializable data object Channels : Route
+ @Serializable data object Channels : ChannelsRoute
}
-object ConnectionsRoutes {
- @Serializable data object ConnectionsGraph : Graph
+@Serializable
+sealed interface ConnectionsRoute : Route {
+ @Serializable data object ConnectionsGraph : ConnectionsRoute, Graph
- @Serializable data object Connections : Route
+ @Serializable data object Connections : ConnectionsRoute
}
-object ContactsRoutes {
- @Serializable data object ContactsGraph : Graph
+@Serializable
+sealed interface ContactsRoute : Route {
+ @Serializable data object ContactsGraph : ContactsRoute, Graph
- @Serializable data object Contacts : Route
+ @Serializable data object Contacts : ContactsRoute
- @Serializable data class Messages(val contactKey: String, val message: String = "") : Route
+ @Serializable data class Messages(val contactKey: String, val message: String = "") : ContactsRoute
- @Serializable data class Share(val message: String) : Route
+ @Serializable data class Share(val message: String) : ContactsRoute
- @Serializable data object QuickChat : Route
+ @Serializable data object QuickChat : ContactsRoute
}
-object MapRoutes {
- @Serializable data class Map(val waypointId: Int? = null) : Route
+@Serializable
+sealed interface MapRoute : Route {
+ @Serializable data class Map(val waypointId: Int? = null) : MapRoute
}
-object NodesRoutes {
- @Serializable data object NodesGraph : Graph
+@Serializable
+sealed interface NodesRoute : Route {
+ @Serializable data object NodesGraph : NodesRoute, Graph
- @Serializable data object Nodes : Route
+ @Serializable data object Nodes : NodesRoute
- @Serializable data class NodeDetailGraph(val destNum: Int? = null) : Graph
+ @Serializable data class NodeDetailGraph(val destNum: Int? = null) : NodesRoute, Graph
- @Serializable data class NodeDetail(val destNum: Int? = null) : Route
+ @Serializable data class NodeDetail(val destNum: Int? = null) : NodesRoute
}
-object NodeDetailRoutes {
- @Serializable data class DeviceMetrics(val destNum: Int) : Route
+@Serializable
+sealed interface NodeDetailRoute : Route {
+ @Serializable data class DeviceMetrics(val destNum: Int) : NodeDetailRoute
- @Serializable data class NodeMap(val destNum: Int) : Route
+ @Serializable data class NodeMap(val destNum: Int) : NodeDetailRoute
- @Serializable data class PositionLog(val destNum: Int) : Route
+ @Serializable data class PositionLog(val destNum: Int) : NodeDetailRoute
- @Serializable data class EnvironmentMetrics(val destNum: Int) : Route
+ @Serializable data class EnvironmentMetrics(val destNum: Int) : NodeDetailRoute
- @Serializable data class SignalMetrics(val destNum: Int) : Route
+ @Serializable data class SignalMetrics(val destNum: Int) : NodeDetailRoute
- @Serializable data class PowerMetrics(val destNum: Int) : Route
+ @Serializable data class PowerMetrics(val destNum: Int) : NodeDetailRoute
- @Serializable data class TracerouteLog(val destNum: Int) : Route
+ @Serializable data class TracerouteLog(val destNum: Int) : NodeDetailRoute
- @Serializable data class TracerouteMap(val destNum: Int, val requestId: Int, val logUuid: String? = null) : Route
+ @Serializable data class TracerouteMap(val destNum: Int, val requestId: Int, val logUuid: String? = null) : NodeDetailRoute
- @Serializable data class HostMetricsLog(val destNum: Int) : Route
+ @Serializable data class HostMetricsLog(val destNum: Int) : NodeDetailRoute
- @Serializable data class PaxMetrics(val destNum: Int) : Route
+ @Serializable data class PaxMetrics(val destNum: Int) : NodeDetailRoute
- @Serializable data class NeighborInfoLog(val destNum: Int) : Route
+ @Serializable data class NeighborInfoLog(val destNum: Int) : NodeDetailRoute
}
-object SettingsRoutes {
- @Serializable data class SettingsGraph(val destNum: Int? = null) : Graph
+@Serializable
+sealed interface SettingsRoute : Route {
+ @Serializable data class SettingsGraph(val destNum: Int? = null) : SettingsRoute, Graph
- @Serializable data class Settings(val destNum: Int? = null) : Route
+ @Serializable data class Settings(val destNum: Int? = null) : SettingsRoute
- @Serializable data object DeviceConfiguration : Route
+ @Serializable data object DeviceConfiguration : SettingsRoute
- @Serializable data object ModuleConfiguration : Route
+ @Serializable data object ModuleConfiguration : SettingsRoute
- @Serializable data object Administration : Route
+ @Serializable data object Administration : SettingsRoute
// region radio Config Routes
- @Serializable data object User : Route
+ @Serializable data object User : SettingsRoute
- @Serializable data object ChannelConfig : Route
+ @Serializable data object ChannelConfig : SettingsRoute
- @Serializable data object Device : Route
+ @Serializable data object Device : SettingsRoute
- @Serializable data object Position : Route
+ @Serializable data object Position : SettingsRoute
- @Serializable data object Power : Route
+ @Serializable data object Power : SettingsRoute
- @Serializable data object Network : Route
+ @Serializable data object Network : SettingsRoute
- @Serializable data object Display : Route
+ @Serializable data object Display : SettingsRoute
- @Serializable data object LoRa : Route
+ @Serializable data object LoRa : SettingsRoute
- @Serializable data object Bluetooth : Route
+ @Serializable data object Bluetooth : SettingsRoute
- @Serializable data object Security : Route
+ @Serializable data object Security : SettingsRoute
// endregion
// region module config routes
- @Serializable data object MQTT : Route
+ @Serializable data object MQTT : SettingsRoute
- @Serializable data object Serial : Route
+ @Serializable data object Serial : SettingsRoute
- @Serializable data object ExtNotification : Route
+ @Serializable data object ExtNotification : SettingsRoute
- @Serializable data object StoreForward : Route
+ @Serializable data object StoreForward : SettingsRoute
- @Serializable data object RangeTest : Route
+ @Serializable data object RangeTest : SettingsRoute
- @Serializable data object Telemetry : Route
+ @Serializable data object Telemetry : SettingsRoute
- @Serializable data object CannedMessage : Route
+ @Serializable data object CannedMessage : SettingsRoute
- @Serializable data object Audio : Route
+ @Serializable data object Audio : SettingsRoute
- @Serializable data object RemoteHardware : Route
+ @Serializable data object RemoteHardware : SettingsRoute
- @Serializable data object NeighborInfo : Route
+ @Serializable data object NeighborInfo : SettingsRoute
- @Serializable data object AmbientLighting : Route
+ @Serializable data object AmbientLighting : SettingsRoute
- @Serializable data object DetectionSensor : Route
+ @Serializable data object DetectionSensor : SettingsRoute
- @Serializable data object Paxcounter : Route
+ @Serializable data object Paxcounter : SettingsRoute
- @Serializable data object StatusMessage : Route
+ @Serializable data object StatusMessage : SettingsRoute
- @Serializable data object TrafficManagement : Route
+ @Serializable data object TrafficManagement : SettingsRoute
- @Serializable data object TAK : Route
+ @Serializable data object TAK : SettingsRoute
// endregion
// region advanced config routes
- @Serializable data object CleanNodeDb : Route
+ @Serializable data object CleanNodeDb : SettingsRoute
- @Serializable data object DebugPanel : Route
+ @Serializable data object DebugPanel : SettingsRoute
- @Serializable data object About : Route
+ @Serializable data object About : SettingsRoute
- @Serializable data object FilterSettings : Route
+ @Serializable data object FilterSettings : SettingsRoute
// endregion
}
-object FirmwareRoutes {
- @Serializable data object FirmwareGraph : Graph
+@Serializable
+sealed interface FirmwareRoute : Route {
+ @Serializable data object FirmwareGraph : FirmwareRoute, Graph
- @Serializable data object FirmwareUpdate : Route
+ @Serializable data object FirmwareUpdate : FirmwareRoute
}
-object WifiProvisionRoutes {
- @Serializable data object WifiProvisionGraph : Graph
+@Serializable
+sealed interface WifiProvisionRoute : Route {
+ @Serializable data object WifiProvisionGraph : WifiProvisionRoute, Graph
- @Serializable data class WifiProvision(val address: String? = null) : Route
+ @Serializable data class WifiProvision(val address: String? = null) : WifiProvisionRoute
}

diff --git a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt
index b25a610812..5f9603dd32 100644
--- a/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt
+++ b/core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/TopLevelDestination.kt
@@ -32,11 +32,11 @@ import org.meshtastic.core.resources.nodes
* and Desktop navigation shells.
*/
enum class TopLevelDestination(val label: StringResource, val route: Route) {
- Conversations(Res.string.conversations, ContactsRoutes.ContactsGraph),
- Nodes(Res.string.nodes, NodesRoutes.NodesGraph),
- Map(Res.string.map, MapRoutes.Map()),
- Settings(Res.string.bottom_nav_settings, SettingsRoutes.SettingsGraph()),
- Connections(Res.string.connections, ConnectionsRoutes.ConnectionsGraph),
+ Conversations(Res.string.conversations, ContactsRoute.ContactsGraph),
+ Nodes(Res.string.nodes, NodesRoute.NodesGraph),
+ Map(Res.string.map, MapRoute.Map()),
+ Settings(Res.string.bottom_nav_settings, SettingsRoute.SettingsGraph()),
+ Connections(Res.string.connections, ConnectionsRoute.ConnectionsGraph),
;
companion object {

diff --git a/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt b/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt
index 60ba3f6eb3..c4d3ac0442 100644
--- a/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt
+++ b/core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/MultiBackstackTest.kt
@@ -29,7 +29,7 @@ class MultiBackstackTest {
val multiBackstack = MultiBackstack(startTab)
val nodesStack =
- NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoutes.Nodes)) }
+ NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoute.Nodes)) }
val mapStack = NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Map.route)) }
multiBackstack.backStacks =
@@ -51,7 +51,7 @@ class MultiBackstackTest {
val multiBackstack = MultiBackstack(startTab)
val nodesStack =
- NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoutes.Nodes)) }
+ NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoute.Nodes)) }
multiBackstack.backStacks = mapOf(TopLevelDestination.Nodes.route to nodesStack)
assertEquals(2, multiBackstack.activeBackStack.size)
@@ -68,7 +68,7 @@ class MultiBackstackTest {
val multiBackstack = MultiBackstack(startTab)
val nodesStack =
- NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoutes.Nodes)) }
+ NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Nodes.route, NodesRoute.Nodes)) }
multiBackstack.backStacks = mapOf(TopLevelDestination.Nodes.route to nodesStack)
multiBackstack.goBack()
@@ -104,11 +104,11 @@ class MultiBackstackTest {
val settingsStack = NavBackStack<NavKey>().apply { addAll(listOf(TopLevelDestination.Settings.route)) }
multiBackstack.backStacks = mapOf(TopLevelDestination.Settings.route to settingsStack)
- val deepLinkPath = listOf(TopLevelDestination.Settings.route, SettingsRoutes.About)
+ val deepLinkPath = listOf(TopLevelDestination.Settings.route, SettingsRoute.About)
multiBackstack.handleDeepLink(deepLinkPath)
assertEquals(TopLevelDestination.Settings.route, multiBackstack.currentTabRoute)
assertEquals(2, multiBackstack.activeBackStack.size)
- assertEquals(SettingsRoutes.About, multiBackstack.activeBackStack.last())
+ assertEquals(SettingsRoute.About, multiBackstack.activeBackStack.last())
}
}

diff --git a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt
index 6ade7e3b2d..8c96e88a4a 100644
--- a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt
+++ b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticAppShell.kt
@@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import org.meshtastic.core.navigation.MultiBackstack
-import org.meshtastic.core.navigation.NodeDetailRoutes
+import org.meshtastic.core.navigation.NodeDetailRoute
import org.meshtastic.core.ui.viewmodel.UIViewModel
/**
@@ -44,7 +44,7 @@ fun MeshtasticAppShell(
uiViewModel = uiViewModel,
onNavigateToTracerouteMap = { destNum, requestId, logUuid ->
multiBackstack.activeBackStack.add(
- NodeDetailRoutes.TracerouteMap(destNum = destNum, requestId = requestId, logUuid = logUuid),
+ NodeDetailRoute.TracerouteMap(destNum = destNum, requestId = requestId, logUuid = logUuid),
)
},
)

diff --git a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt
index 1e0fae0c50..9f1f366372 100644
--- a/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt
+++ b/core/ui/src/commonMain/kotlin/org/meshtastic/core/ui/component/MeshtasticNavigationSuite.kt
@@ -50,9 +50,9 @@ import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.resources.vectorResource
import org.meshtastic.core.model.ConnectionState
import org.meshtastic.core.model.DeviceType
-import org.meshtastic.core.navigation.ContactsRoutes
+import org.meshtastic.core.navigation.ContactsRoute
import org.meshtastic.core.navigation.MultiBackstack
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.navigation.TopLevelDestination
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.connected
@@ -141,7 +141,7 @@ private fun handleNavigation(
val currentKey = multiBackstack.activeBackStack.lastOrNull()
when (destination) {
TopLevelDestination.Nodes -> {
- val onNodesList = currentKey is NodesRoutes.NodesGraph || currentKey is NodesRoutes.Nodes
+ val onNodesList = currentKey is NodesRoute.NodesGraph || currentKey is NodesRoute.Nodes
if (!onNodesList) {
multiBackstack.navigateTopLevel(destination.route)
} else {
@@ -150,7 +150,7 @@ private fun handleNavigation(
}
TopLevelDestination.Conversations -> {
val onConversationsList =
- currentKey is ContactsRoutes.ContactsGraph || currentKey is ContactsRoutes.Contacts
+ currentKey is ContactsRoute.ContactsGraph || currentKey is ContactsRoute.Contacts
if (!onConversationsList) {
multiBackstack.navigateTopLevel(destination.route)
} else {

diff --git a/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt b/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt
index bc0d3a144f..0a450c0079 100644
--- a/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt
+++ b/desktop/src/main/kotlin/org/meshtastic/desktop/Main.kt
@@ -62,7 +62,7 @@ import org.jetbrains.skia.Image
import org.koin.core.context.startKoin
import org.meshtastic.core.common.util.MeshtasticUri
import org.meshtastic.core.database.desktopDataDir
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.core.navigation.TopLevelDestination
import org.meshtastic.core.navigation.rememberMultiBackstack
import org.meshtastic.core.repository.UiPrefs
@@ -241,7 +241,7 @@ fun main(args: Array<String>) = application(exitProcessOnExit = false) {
true
}
event.key == Key.Slash -> {
- backStack.add(SettingsRoutes.About)
+ backStack.add(SettingsRoute.About)
true
}
else -> false

diff --git a/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt b/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt
index 01fec03b29..d14c2fe985 100644
--- a/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt
+++ b/desktop/src/test/kotlin/org/meshtastic/desktop/ui/DesktopTopLevelDestinationParityTest.kt
@@ -16,13 +16,13 @@
*/
package org.meshtastic.desktop.ui
-import org.meshtastic.core.navigation.ConnectionsRoutes
-import org.meshtastic.core.navigation.ContactsRoutes
-import org.meshtastic.core.navigation.FirmwareRoutes
-import org.meshtastic.core.navigation.MapRoutes
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.ConnectionsRoute
+import org.meshtastic.core.navigation.ContactsRoute
+import org.meshtastic.core.navigation.FirmwareRoute
+import org.meshtastic.core.navigation.MapRoute
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.core.navigation.TopLevelDestination
import kotlin.reflect.KClass
import kotlin.test.Test
@@ -41,11 +41,11 @@ class DesktopTopLevelDestinationParityTest {
val androidParityRoutes: Set<KClass<out Route>> =
setOf(
- ContactsRoutes.ContactsGraph::class,
- NodesRoutes.NodesGraph::class,
- MapRoutes.Map::class,
- SettingsRoutes.SettingsGraph::class,
- ConnectionsRoutes.ConnectionsGraph::class,
+ ContactsRoute.ContactsGraph::class,
+ NodesRoute.NodesGraph::class,
+ MapRoute.Map::class,
+ SettingsRoute.SettingsGraph::class,
+ ConnectionsRoute.ConnectionsGraph::class,
)
assertEquals(
@@ -60,7 +60,7 @@ class DesktopTopLevelDestinationParityTest {
val desktopRoutes: Set<KClass<out Route>> = TopLevelDestination.entries.map { it.route::class }.toSet()
assertFalse(
- actual = desktopRoutes.contains(FirmwareRoutes.FirmwareGraph::class),
+ actual = desktopRoutes.contains(FirmwareRoute.FirmwareGraph::class),
message = "Firmware must stay in-flow and not appear in the desktop top-level rail",
)
}

diff --git a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt
index eabd920eb2..152e880cb2 100644
--- a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt
+++ b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt
@@ -20,30 +20,30 @@ import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import org.koin.compose.viewmodel.koinViewModel
-import org.meshtastic.core.navigation.ConnectionsRoutes
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.ConnectionsRoute
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.feature.connections.ScannerViewModel
import org.meshtastic.feature.connections.ui.ConnectionsScreen
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
-/** Navigation graph for for the top level ConnectionsScreen - [ConnectionsRoutes.Connections]. */
+/** Navigation graph for for the top level ConnectionsScreen - [ConnectionsRoute.Connections]. */
fun EntryProviderScope<NavKey>.connectionsGraph(backStack: NavBackStack<NavKey>) {
- entry<ConnectionsRoutes.ConnectionsGraph> {
+ entry<ConnectionsRoute.ConnectionsGraph> {
ConnectionsScreen(
scanModel = koinViewModel<ScannerViewModel>(),
radioConfigViewModel = koinViewModel<RadioConfigViewModel>(),
- onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) },
- onNavigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) },
+ onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) },
+ onNavigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) },
onConfigNavigate = { route -> backStack.add(route) },
)
}
- entry<ConnectionsRoutes.Connections> {
+ entry<ConnectionsRoute.Connections> {
ConnectionsScreen(
scanModel = koinViewModel<ScannerViewModel>(),
radioConfigViewModel = koinViewModel<RadioConfigViewModel>(),
- onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) },
- onNavigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) },
+ onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) },
+ onNavigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) },
onConfigNavigate = { route -> backStack.add(route) },
)
}

diff --git a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt
index 05a172e1fa..828b7be2f9 100644
--- a/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt
+++ b/feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/ConnectionsScreen.kt
@@ -51,7 +51,7 @@ import org.koin.compose.viewmodel.koinViewModel
import org.meshtastic.core.model.ConnectionState
import org.meshtastic.core.model.DeviceType
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.connected
import org.meshtastic.core.resources.connected_device
@@ -125,8 +125,8 @@ fun ConnectionsScreen(
getNavRouteFrom(radioConfigState.route)?.let { route ->
isWaiting = false
radioConfigViewModel.clearPacketResponse()
- if (route == SettingsRoutes.LoRa) {
- onConfigNavigate(SettingsRoutes.LoRa)
+ if (route == SettingsRoute.LoRa) {
+ onConfigNavigate(SettingsRoute.LoRa)
}
}
},

diff --git a/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt b/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt
index 9ab1320b94..7980ad96af 100644
--- a/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt
+++ b/feature/firmware/src/commonMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt
@@ -21,14 +21,14 @@ import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import org.koin.compose.viewmodel.koinViewModel
-import org.meshtastic.core.navigation.FirmwareRoutes
+import org.meshtastic.core.navigation.FirmwareRoute
import org.meshtastic.feature.firmware.FirmwareUpdateScreen
import org.meshtastic.feature.firmware.FirmwareUpdateViewModel
/** Registers the firmware update screen entries into the Navigation 3 entry provider. */
fun EntryProviderScope<NavKey>.firmwareGraph(backStack: NavBackStack<NavKey>) {
- entry<FirmwareRoutes.FirmwareGraph> { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) }
- entry<FirmwareRoutes.FirmwareUpdate> { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) }
+ entry<FirmwareRoute.FirmwareGraph> { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) }
+ entry<FirmwareRoute.FirmwareUpdate> { FirmwareScreen(onNavigateUp = { backStack.removeLastOrNull() }) }
}
@Composable

diff --git a/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt b/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt
index fb921bdde0..2c0b5e7b84 100644
--- a/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt
+++ b/feature/map/src/commonMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt
@@ -19,15 +19,15 @@ package org.meshtastic.feature.map.navigation
import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
-import org.meshtastic.core.navigation.MapRoutes
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.MapRoute
+import org.meshtastic.core.navigation.NodesRoute
fun EntryProviderScope<NavKey>.mapGraph(backStack: NavBackStack<NavKey>) {
- entry<MapRoutes.Map> { args ->
+ entry<MapRoute.Map> { args ->
val mapScreen = org.meshtastic.core.ui.util.LocalMapMainScreenProvider.current
mapScreen(
- { backStack.add(NodesRoutes.NodeDetail(it)) }, // onClickNodeChip
- { backStack.add(NodesRoutes.NodeDetail(it)) }, // navigateToNodeDetails
+ { backStack.add(NodesRoute.NodeDetail(it)) }, // onClickNodeChip
+ { backStack.add(NodesRoute.NodeDetail(it)) }, // navigateToNodeDetails
args.waypointId,
)
}

diff --git a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt
index 1e83f80395..0f347f9804 100644
--- a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt
+++ b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt
@@ -27,8 +27,8 @@ import androidx.navigation3.runtime.NavKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import org.koin.compose.viewmodel.koinViewModel
-import org.meshtastic.core.navigation.ContactsRoutes
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.ContactsRoute
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.navigation.replaceLast
import org.meshtastic.core.ui.component.ScrollToTopEvent
import org.meshtastic.feature.messaging.QuickChatScreen
@@ -43,15 +43,15 @@ fun EntryProviderScope<NavKey>.contactsGraph(
backStack: NavBackStack<NavKey>,
scrollToTopEvents: Flow<ScrollToTopEvent> = MutableSharedFlow(),
) {
- entry<ContactsRoutes.ContactsGraph>(metadata = { ListDetailSceneStrategy.listPane() }) {
+ entry<ContactsRoute.ContactsGraph>(metadata = { ListDetailSceneStrategy.listPane() }) {
ContactsEntryContent(backStack = backStack, scrollToTopEvents = scrollToTopEvents)
}
- entry<ContactsRoutes.Contacts>(metadata = { ListDetailSceneStrategy.listPane() }) {
+ entry<ContactsRoute.Contacts>(metadata = { ListDetailSceneStrategy.listPane() }) {
ContactsEntryContent(backStack = backStack, scrollToTopEvents = scrollToTopEvents)
}
- entry<ContactsRoutes.Messages>(metadata = { ListDetailSceneStrategy.detailPane() }) { args ->
+ entry<ContactsRoute.Messages>(metadata = { ListDetailSceneStrategy.detailPane() }) { args ->
val contactKey = args.contactKey
val messageViewModel: org.meshtastic.feature.messaging.MessageViewModel =
koinViewModel(key = "messages-$contactKey")
@@ -61,23 +61,23 @@ fun EntryProviderScope<NavKey>.contactsGraph(
contactKey = contactKey,
message = args.message,
viewModel = messageViewModel,
- navigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) },
- navigateToQuickChatOptions = { backStack.add(org.meshtastic.core.navigation.ContactsRoutes.QuickChat) },
+ navigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) },
+ navigateToQuickChatOptions = { backStack.add(org.meshtastic.core.navigation.ContactsRoute.QuickChat) },
onNavigateBack = { backStack.removeLastOrNull() },
)
}
- entry<ContactsRoutes.Share>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
+ entry<ContactsRoute.Share>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
val message = args.message
val viewModel = koinViewModel<ContactsViewModel>()
ShareScreen(
viewModel = viewModel,
- onConfirm = { contactKey -> backStack.replaceLast(ContactsRoutes.Messages(contactKey, message)) },
+ onConfirm = { contactKey -> backStack.replaceLast(ContactsRoute.Messages(contactKey, message)) },
onNavigateUp = { backStack.removeLastOrNull() },
)
}
- entry<ContactsRoutes.QuickChat>(metadata = { ListDetailSceneStrategy.extraPane() }) {
+ entry<ContactsRoute.QuickChat>(metadata = { ListDetailSceneStrategy.extraPane() }) {
val viewModel = koinViewModel<QuickChatViewModel>()
QuickChatScreen(viewModel = viewModel, onNavigateUp = { backStack.removeLastOrNull() })
}

diff --git a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt
index df3d5a7ad3..d8f7eeae04 100644
--- a/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt
+++ b/feature/messaging/src/commonMain/kotlin/org/meshtastic/feature/messaging/ui/contact/AdaptiveContactsScreen.kt
@@ -21,9 +21,9 @@ import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import kotlinx.coroutines.flow.Flow
import org.meshtastic.core.common.util.MeshtasticUri
-import org.meshtastic.core.navigation.ChannelsRoutes
-import org.meshtastic.core.navigation.ContactsRoutes
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.ChannelsRoute
+import org.meshtastic.core.navigation.ContactsRoute
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.ui.component.ScrollToTopEvent
import org.meshtastic.proto.ChannelSet
import org.meshtastic.proto.SharedContact
@@ -40,16 +40,16 @@ fun AdaptiveContactsScreen(
onClearRequestChannelUrl: () -> Unit,
) {
ContactsScreen(
- onNavigateToShare = { backStack.add(ChannelsRoutes.ChannelsGraph) },
+ onNavigateToShare = { backStack.add(ChannelsRoute.ChannelsGraph) },
sharedContactRequested = sharedContactRequested,
requestChannelSet = requestChannelSet,
onHandleDeepLink = onHandleDeepLink,
onClearSharedContactRequested = onClearSharedContactRequested,
onClearRequestChannelUrl = onClearRequestChannelUrl,
viewModel = contactsViewModel,
- onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) },
- onNavigateToMessages = { contactKey -> backStack.add(ContactsRoutes.Messages(contactKey)) },
- onNavigateToNodeDetails = { backStack.add(NodesRoutes.NodeDetail(it)) },
+ onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) },
+ onNavigateToMessages = { contactKey -> backStack.add(ContactsRoute.Messages(contactKey)) },
+ onNavigateToNodeDetails = { backStack.add(NodesRoute.NodeDetail(it)) },
scrollToTopEvents = scrollToTopEvents,
activeContactKey = null,
)

diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt
index 5cd4612109..23ef010e86 100644
--- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt
+++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt
@@ -27,7 +27,7 @@ import org.meshtastic.core.database.entity.asDeviceVersion
import org.meshtastic.core.model.DeviceVersion
import org.meshtastic.core.model.Node
import org.meshtastic.core.model.service.ServiceAction
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.administration
import org.meshtastic.core.resources.firmware
@@ -77,7 +77,7 @@ fun AdministrationSection(
leadingIcon = MeshtasticIcons.Settings,
enabled = metricsState.isLocal || node.metadata != null,
) {
- onAction(NodeDetailAction.Navigate(SettingsRoutes.Settings(node.num)))
+ onAction(NodeDetailAction.Navigate(SettingsRoute.Settings(node.num)))
}
}
}

diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt
index b4db1b3585..3bd4a4a5ba 100644
--- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt
+++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/model/LogsType.kt
@@ -18,7 +18,7 @@ package org.meshtastic.feature.node.model
import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.StringResource
-import org.meshtastic.core.navigation.NodeDetailRoutes
+import org.meshtastic.core.navigation.NodeDetailRoute
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.device_metrics_log
@@ -43,14 +43,14 @@ import org.meshtastic.core.resources.signal_quality
import org.meshtastic.core.resources.traceroute_log
enum class LogsType(val titleRes: StringResource, val icon: DrawableResource, val routeFactory: (Int) -> Route) {
- DEVICE(Res.string.device_metrics_log, Res.drawable.ic_charging_station, { NodeDetailRoutes.DeviceMetrics(it) }),
- NODE_MAP(Res.string.node_map, Res.drawable.ic_map, { NodeDetailRoutes.NodeMap(it) }),
- POSITIONS(Res.string.position_log, Res.drawable.ic_location_on, { NodeDetailRoutes.PositionLog(it) }),
- ENVIRONMENT(Res.string.env_metrics_log, Res.drawable.ic_thermostat, { NodeDetailRoutes.EnvironmentMetrics(it) }),
- SIGNAL(Res.string.signal_quality, Res.drawable.ic_signal_cellular_alt, { NodeDetailRoutes.SignalMetrics(it) }),
- POWER(Res.string.power_metrics_log, Res.drawable.ic_power, { NodeDetailRoutes.PowerMetrics(it) }),
- TRACEROUTE(Res.string.traceroute_log, Res.drawable.ic_route, { NodeDetailRoutes.TracerouteLog(it) }),
- NEIGHBOR_INFO(Res.string.neighbor_info, Res.drawable.ic_groups, { NodeDetailRoutes.NeighborInfoLog(it) }),
- HOST(Res.string.host_metrics_log, Res.drawable.ic_memory, { NodeDetailRoutes.HostMetricsLog(it) }),
- PAX(Res.string.pax_metrics_log, Res.drawable.ic_people, { NodeDetailRoutes.PaxMetrics(it) }),
+ DEVICE(Res.string.device_metrics_log, Res.drawable.ic_charging_station, { NodeDetailRoute.DeviceMetrics(it) }),
+ NODE_MAP(Res.string.node_map, Res.drawable.ic_map, { NodeDetailRoute.NodeMap(it) }),
+ POSITIONS(Res.string.position_log, Res.drawable.ic_location_on, { NodeDetailRoute.PositionLog(it) }),
+ ENVIRONMENT(Res.string.env_metrics_log, Res.drawable.ic_thermostat, { NodeDetailRoute.EnvironmentMetrics(it) }),
+ SIGNAL(Res.string.signal_quality, Res.drawable.ic_signal_cellular_alt, { NodeDetailRoute.SignalMetrics(it) }),
+ POWER(Res.string.power_metrics_log, Res.drawable.ic_power, { NodeDetailRoute.PowerMetrics(it) }),
+ TRACEROUTE(Res.string.traceroute_log, Res.drawable.ic_route, { NodeDetailRoute.TracerouteLog(it) }),
+ NEIGHBOR_INFO(Res.string.neighbor_info, Res.drawable.ic_groups, { NodeDetailRoute.NeighborInfoLog(it) }),
+ HOST(Res.string.host_metrics_log, Res.drawable.ic_memory, { NodeDetailRoute.HostMetricsLog(it) }),
+ PAX(Res.string.pax_metrics_log, Res.drawable.ic_people, { NodeDetailRoute.PaxMetrics(it) }),
}

diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt
index ce8bd665e7..cca1b67bff 100644
--- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt
+++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt
@@ -21,8 +21,8 @@ import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import kotlinx.coroutines.flow.Flow
import org.koin.compose.viewmodel.koinViewModel
-import org.meshtastic.core.navigation.ChannelsRoutes
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.ChannelsRoute
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.ui.component.ScrollToTopEvent
import org.meshtastic.feature.node.list.NodeListScreen
import org.meshtastic.feature.node.list.NodeListViewModel
@@ -37,8 +37,8 @@ fun AdaptiveNodeListScreen(
NodeListScreen(
viewModel = nodeListViewModel,
- navigateToNodeDetails = { nodeId -> backStack.add(NodesRoutes.NodeDetail(nodeId)) },
- onNavigateToChannels = { backStack.add(ChannelsRoutes.ChannelsGraph) },
+ navigateToNodeDetails = { nodeId -> backStack.add(NodesRoute.NodeDetail(nodeId)) },
+ onNavigateToChannels = { backStack.add(ChannelsRoute.ChannelsGraph) },
scrollToTopEvents = scrollToTopEvents,
activeNodeId = null,
onHandleDeepLink = onHandleDeepLink,

diff --git a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt
index abfc38905d..b80d7cba5d 100644
--- a/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt
+++ b/feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt
@@ -28,9 +28,9 @@ import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.StringResource
import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf
-import org.meshtastic.core.navigation.ContactsRoutes
-import org.meshtastic.core.navigation.NodeDetailRoutes
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.ContactsRoute
+import org.meshtastic.core.navigation.NodeDetailRoute
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.navigation.Route
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.device
@@ -74,7 +74,7 @@ fun EntryProviderScope<NavKey>.nodesGraph(
scrollToTopEvents: Flow<ScrollToTopEvent> = MutableSharedFlow(),
onHandleDeepLink: (org.meshtastic.core.common.util.MeshtasticUri, onInvalid: () -> Unit) -> Unit = { _, _ -> },
) {
- entry<NodesRoutes.NodesGraph>(metadata = { ListDetailSceneStrategy.listPane() }) {
+ entry<NodesRoute.NodesGraph>(metadata = { ListDetailSceneStrategy.listPane() }) {
AdaptiveNodeListScreen(
backStack = backStack,
scrollToTopEvents = scrollToTopEvents,
@@ -82,7 +82,7 @@ fun EntryProviderScope<NavKey>.nodesGraph(
)
}
- entry<NodesRoutes.Nodes>(metadata = { ListDetailSceneStrategy.listPane() }) {
+ entry<NodesRoute.Nodes>(metadata = { ListDetailSceneStrategy.listPane() }) {
AdaptiveNodeListScreen(
backStack = backStack,
scrollToTopEvents = scrollToTopEvents,
@@ -100,7 +100,7 @@ fun EntryProviderScope<NavKey>.nodeDetailGraph(
scrollToTopEvents: Flow<ScrollToTopEvent>,
onHandleDeepLink: (org.meshtastic.core.common.util.MeshtasticUri, onInvalid: () -> Unit) -> Unit = { _, _ -> },
) {
- entry<NodesRoutes.NodeDetailGraph>(metadata = { ListDetailSceneStrategy.listPane() }) { args ->
+ entry<NodesRoute.NodeDetailGraph>(metadata = { ListDetailSceneStrategy.listPane() }) { args ->
AdaptiveNodeListScreen(
backStack = backStack,
scrollToTopEvents = scrollToTopEvents,
@@ -108,7 +108,7 @@ fun EntryProviderScope<NavKey>.nodeDetailGraph(
)
}
- entry<NodesRoutes.NodeDetail>(metadata = { ListDetailSceneStrategy.detailPane() }) { args ->
+ entry<NodesRoute.NodeDetail>(metadata = { ListDetailSceneStrategy.detailPane() }) { args ->
val nodeDetailViewModel: NodeDetailViewModel = koinViewModel()
val compassViewModel: CompassViewModel = koinViewModel()
val destNum = args.destNum ?: 0 // Handle nullable destNum if needed
@@ -116,18 +116,18 @@ fun EntryProviderScope<NavKey>.nodeDetailGraph(
nodeId = destNum,
viewModel = nodeDetailViewModel,
compassViewModel = compassViewModel,
- navigateToMessages = { backStack.add(ContactsRoutes.Messages(it)) },
+ navigateToMessages = { backStack.add(ContactsRoute.Messages(it)) },
onNavigate = { backStack.add(it) },
onNavigateUp = { backStack.removeLastOrNull() },
)
}
- entry<NodeDetailRoutes.NodeMap>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
+ entry<NodeDetailRoute.NodeMap>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
val mapScreen = org.meshtastic.core.ui.util.LocalNodeMapScreenProvider.current
mapScreen(args.destNum) { backStack.removeLastOrNull() }
}
- entry<NodeDetailRoutes.TracerouteLog>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
+ entry<NodeDetailRoute.TracerouteLog>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
val metricsViewModel = koinViewModel<MetricsViewModel> { parametersOf(args.destNum) }
metricsViewModel.setNodeId(args.destNum)
@@ -136,7 +136,7 @@ fun EntryProviderScope<NavKey>.nodeDetailGraph(
onNavigateUp = { backStack.removeLastOrNull() },
onViewOnMap = { requestId, responseLogUuid ->
backStack.add(
- NodeDetailRoutes.TracerouteMap(
+ NodeDetailRoute.TracerouteMap(
destNum = args.destNum,
requestId = requestId,
logUuid = responseLogUuid,
@@ -146,40 +146,40 @@ fun EntryProviderScope<NavKey>.nodeDetailGraph(
)
}
- entry<NodeDetailRoutes.TracerouteMap>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
+ entry<NodeDetailRoute.TracerouteMap>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
val tracerouteMapScreen = org.meshtastic.core.ui.util.LocalTracerouteMapScreenProvider.current
tracerouteMapScreen(args.destNum, args.requestId, args.logUuid) { backStack.removeLastOrNull() }
}
- NodeDetailRoute.entries.forEach { routeInfo ->
+ NodeDetailScreen.entries.forEach { routeInfo ->
when (routeInfo.routeClass) {
- NodeDetailRoutes.DeviceMetrics::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.DeviceMetrics>(backStack, routeInfo) { it.destNum }
- NodeDetailRoutes.PositionLog::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.PositionLog>(backStack, routeInfo) { it.destNum }
- NodeDetailRoutes.EnvironmentMetrics::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.EnvironmentMetrics>(backStack, routeInfo) { it.destNum }
- NodeDetailRoutes.SignalMetrics::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.SignalMetrics>(backStack, routeInfo) { it.destNum }
- NodeDetailRoutes.PowerMetrics::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.PowerMetrics>(backStack, routeInfo) { it.destNum }
- NodeDetailRoutes.HostMetricsLog::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.HostMetricsLog>(backStack, routeInfo) { it.destNum }
- NodeDetailRoutes.PaxMetrics::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.PaxMetrics>(backStack, routeInfo) { it.destNum }
- NodeDetailRoutes.NeighborInfoLog::class ->
- addNodeDetailScreenComposable<NodeDetailRoutes.NeighborInfoLog>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.DeviceMetrics::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.DeviceMetrics>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.PositionLog::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.PositionLog>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.EnvironmentMetrics::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.EnvironmentMetrics>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.SignalMetrics::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.SignalMetrics>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.PowerMetrics::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.PowerMetrics>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.HostMetricsLog::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.HostMetricsLog>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.PaxMetrics::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.PaxMetrics>(backStack, routeInfo) { it.destNum }
+ NodeDetailRoute.NeighborInfoLog::class ->
+ addNodeDetailScreenComposable<NodeDetailRoute.NeighborInfoLog>(backStack, routeInfo) { it.destNum }
else -> Unit
}
}
}
-fun NavKey.isNodeDetailRoute(): Boolean = NodeDetailRoute.entries.any { this::class == it.routeClass }
+fun NavKey.isNodeDetailRoute(): Boolean = NodeDetailScreen.entries.any { this::class == it.routeClass }
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
private inline fun <reified R : Route> EntryProviderScope<NavKey>.addNodeDetailScreenComposable(
backStack: NavBackStack<NavKey>,
- routeInfo: NodeDetailRoute,
+ routeInfo: NodeDetailScreen,
crossinline getDestNum: (R) -> Int,
) {
entry<R>(metadata = { ListDetailSceneStrategy.extraPane() }) { args ->
@@ -192,7 +192,7 @@ private inline fun <reified R : Route> EntryProviderScope<NavKey>.addNodeDetailS
}
/** Expect declaration for the platform-specific traceroute map screen. */
-enum class NodeDetailRoute(
+enum class NodeDetailScreen(
val title: StringResource,
val routeClass: KClass<out Route>,
val icon: DrawableResource? = null,
@@ -200,55 +200,55 @@ enum class NodeDetailRoute(
) {
DEVICE(
Res.string.device,
- NodeDetailRoutes.DeviceMetrics::class,
+ NodeDetailRoute.DeviceMetrics::class,
Res.drawable.ic_router,
{ metricsVM, onNavigateUp -> DeviceMetricsScreen(metricsVM, onNavigateUp) },
),
POSITION_LOG(
Res.string.position_log,
- NodeDetailRoutes.PositionLog::class,
+ NodeDetailRoute.PositionLog::class,
Res.drawable.ic_location_on,
{ metricsVM, onNavigateUp -> PositionLogScreen(metricsVM, onNavigateUp) },
),
ENVIRONMENT(
Res.string.environment,
- NodeDetailRoutes.EnvironmentMetrics::class,
+ NodeDetailRoute.EnvironmentMetrics::class,
Res.drawable.ic_light_mode,
{ metricsVM, onNavigateUp -> EnvironmentMetricsScreen(metricsVM, onNavigateUp) },
),
SIGNAL(
Res.string.signal,
- NodeDetailRoutes.SignalMetrics::class,
+ NodeDetailRoute.SignalMetrics::class,
Res.drawable.ic_cell_tower,
{ metricsVM, onNavigateUp -> SignalMetricsScreen(metricsVM, onNavigateUp) },
),
TRACEROUTE(
Res.string.traceroute,
- NodeDetailRoutes.TracerouteLog::class,
+ NodeDetailRoute.TracerouteLog::class,
Res.drawable.ic_perm_scan_wifi,
{ metricsVM, onNavigateUp -> TracerouteLogScreen(viewModel = metricsVM, onNavigateUp = onNavigateUp) },
),
NEIGHBOR_INFO(
Res.string.neighbor_info,
- NodeDetailRoutes.NeighborInfoLog::class,
+ NodeDetailRoute.NeighborInfoLog::class,
Res.drawable.ic_groups,
{ metricsVM, onNavigateUp -> NeighborInfoLogScreen(viewModel = metricsVM, onNavigateUp = onNavigateUp) },
),
POWER(
Res.string.power,
- NodeDetailRoutes.PowerMetrics::class,
+ NodeDetailRoute.PowerMetrics::class,
Res.drawable.ic_power,
{ metricsVM, onNavigateUp -> PowerMetricsScreen(metricsVM, onNavigateUp) },
),
HOST(
Res.string.host,
- NodeDetailRoutes.HostMetricsLog::class,
+ NodeDetailRoute.HostMetricsLog::class,
Res.drawable.ic_memory,
{ metricsVM, onNavigateUp -> HostMetricsLogScreen(metricsVM, onNavigateUp) },
),
PAX(
Res.string.pax,
- NodeDetailRoutes.PaxMetrics::class,
+ NodeDetailRoute.PaxMetrics::class,
Res.drawable.ic_people,
{ metricsVM, onNavigateUp -> PaxMetricsScreen(metricsVM, onNavigateUp) },
),

diff --git a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
index ac5efad043..c33c3a293f 100644
--- a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
+++ b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt
@@ -41,8 +41,8 @@ import org.meshtastic.core.common.util.toDate
import org.meshtastic.core.common.util.toInstant
import org.meshtastic.core.common.util.toMeshtasticUri
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
-import org.meshtastic.core.navigation.WifiProvisionRoutes
+import org.meshtastic.core.navigation.SettingsRoute
+import org.meshtastic.core.navigation.WifiProvisionRoute
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.bottom_nav_settings
import org.meshtastic.core.resources.export_configuration
@@ -233,7 +233,7 @@ fun SettingsScreen(
ExpressiveSection(title = stringResource(Res.string.wifi_devices)) {
ListItem(text = stringResource(Res.string.wifi_devices), leadingIcon = MeshtasticIcons.Wifi) {
- onNavigate(WifiProvisionRoutes.WifiProvision())
+ onNavigate(WifiProvisionRoute.WifiProvision())
}
}
@@ -249,7 +249,7 @@ fun SettingsScreen(
excludedModulesUnlocked = excludedModulesUnlocked,
onUnlockExcludedModules = { settingsViewModel.unlockExcludedModules() },
onShowAppIntro = { settingsViewModel.showAppIntro() },
- onNavigateToAbout = { onNavigate(SettingsRoutes.About) },
+ onNavigateToAbout = { onNavigate(SettingsRoute.About) },
)
}
}

diff --git a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt
index 4b9cf369d4..0a35599f5d 100644
--- a/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt
+++ b/feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt
@@ -16,7 +16,7 @@
*/
package org.meshtastic.feature.settings.navigation
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
actual fun getAboutLibrariesJson(): String =
- SettingsRoutes::class.java.getResource("/aboutlibraries.json")?.readText() ?: ""
+ SettingsRoute::class.java.getResource("/aboutlibraries.json")?.readText() ?: ""

diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt
index e065de6270..600554ba30 100644
--- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt
+++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt
@@ -19,7 +19,7 @@ package org.meshtastic.feature.settings.navigation
import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.StringResource
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.bluetooth
import org.meshtastic.core.resources.channels
@@ -50,43 +50,43 @@ enum class ConfigRoute(
val icon: DrawableResource? = null,
val type: Int = 0,
) {
- USER(Res.string.user, SettingsRoutes.User, Res.drawable.ic_person, 0),
- CHANNELS(Res.string.channels, SettingsRoutes.ChannelConfig, Res.drawable.ic_list, 0),
+ USER(Res.string.user, SettingsRoute.User, Res.drawable.ic_person, 0),
+ CHANNELS(Res.string.channels, SettingsRoute.ChannelConfig, Res.drawable.ic_list, 0),
DEVICE(
Res.string.device,
- SettingsRoutes.Device,
+ SettingsRoute.Device,
Res.drawable.ic_router,
AdminMessage.ConfigType.DEVICE_CONFIG.value,
),
POSITION(
Res.string.position,
- SettingsRoutes.Position,
+ SettingsRoute.Position,
Res.drawable.ic_location_on,
AdminMessage.ConfigType.POSITION_CONFIG.value,
),
- POWER(Res.string.power, SettingsRoutes.Power, Res.drawable.ic_power, AdminMessage.ConfigType.POWER_CONFIG.value),
+ POWER(Res.string.power, SettingsRoute.Power, Res.drawable.ic_power, AdminMessage.ConfigType.POWER_CONFIG.value),
NETWORK(
Res.string.network,
- SettingsRoutes.Network,
+ SettingsRoute.Network,
Res.drawable.ic_wifi,
AdminMessage.ConfigType.NETWORK_CONFIG.value,
),
DISPLAY(
Res.string.display,
- SettingsRoutes.Display,
+ SettingsRoute.Display,
Res.drawable.ic_display_settings,
AdminMessage.ConfigType.DISPLAY_CONFIG.value,
),
- LORA(Res.string.lora, SettingsRoutes.LoRa, Res.drawable.ic_cell_tower, AdminMessage.ConfigType.LORA_CONFIG.value),
+ LORA(Res.string.lora, SettingsRoute.LoRa, Res.drawable.ic_cell_tower, AdminMessage.ConfigType.LORA_CONFIG.value),
BLUETOOTH(
Res.string.bluetooth,
- SettingsRoutes.Bluetooth,
+ SettingsRoute.Bluetooth,
Res.drawable.ic_bluetooth,
AdminMessage.ConfigType.BLUETOOTH_CONFIG.value,
),
SECURITY(
Res.string.security,
- SettingsRoutes.Security,
+ SettingsRoute.Security,
Res.drawable.ic_security,
AdminMessage.ConfigType.SECURITY_CONFIG.value,
),

diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt
index 350ca77cca..45a41447ea 100644
--- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt
+++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt
@@ -20,7 +20,7 @@ import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.StringResource
import org.meshtastic.core.model.Capabilities
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.ambient_lighting
import org.meshtastic.core.resources.audio
@@ -64,96 +64,96 @@ enum class ModuleRoute(
val isSupported: (Capabilities) -> Boolean = { true },
val isApplicable: (Config.DeviceConfig.Role?) -> Boolean = { true },
) {
- MQTT(Res.string.mqtt, SettingsRoutes.MQTT, Res.drawable.ic_cloud, AdminMessage.ModuleConfigType.MQTT_CONFIG.value),
+ MQTT(Res.string.mqtt, SettingsRoute.MQTT, Res.drawable.ic_cloud, AdminMessage.ModuleConfigType.MQTT_CONFIG.value),
SERIAL(
Res.string.serial,
- SettingsRoutes.Serial,
+ SettingsRoute.Serial,
Res.drawable.ic_usb,
AdminMessage.ModuleConfigType.SERIAL_CONFIG.value,
),
EXT_NOTIFICATION(
Res.string.external_notification,
- SettingsRoutes.ExtNotification,
+ SettingsRoute.ExtNotification,
Res.drawable.ic_notifications,
AdminMessage.ModuleConfigType.EXTNOTIF_CONFIG.value,
),
STORE_FORWARD(
Res.string.store_forward,
- SettingsRoutes.StoreForward,
+ SettingsRoute.StoreForward,
Res.drawable.ic_terminal,
AdminMessage.ModuleConfigType.STOREFORWARD_CONFIG.value,
),
RANGE_TEST(
Res.string.range_test,
- SettingsRoutes.RangeTest,
+ SettingsRoute.RangeTest,
Res.drawable.ic_speed,
AdminMessage.ModuleConfigType.RANGETEST_CONFIG.value,
),
TELEMETRY(
Res.string.telemetry,
- SettingsRoutes.Telemetry,
+ SettingsRoute.Telemetry,
Res.drawable.ic_data_usage,
AdminMessage.ModuleConfigType.TELEMETRY_CONFIG.value,
),
CANNED_MESSAGE(
Res.string.canned_message,
- SettingsRoutes.CannedMessage,
+ SettingsRoute.CannedMessage,
Res.drawable.ic_message,
AdminMessage.ModuleConfigType.CANNEDMSG_CONFIG.value,
),
AUDIO(
Res.string.audio,
- SettingsRoutes.Audio,
+ SettingsRoute.Audio,
Res.drawable.ic_volume_up,
AdminMessage.ModuleConfigType.AUDIO_CONFIG.value,
),
REMOTE_HARDWARE(
Res.string.remote_hardware,
- SettingsRoutes.RemoteHardware,
+ SettingsRoute.RemoteHardware,
Res.drawable.ic_settings_remote,
AdminMessage.ModuleConfigType.REMOTEHARDWARE_CONFIG.value,
),
NEIGHBOR_INFO(
Res.string.neighbor_info,
- SettingsRoutes.NeighborInfo,
+ SettingsRoute.NeighborInfo,
Res.drawable.ic_people,
AdminMessage.ModuleConfigType.NEIGHBORINFO_CONFIG.value,
),
AMBIENT_LIGHTING(
Res.string.ambient_lighting,
- SettingsRoutes.AmbientLighting,
+ SettingsRoute.AmbientLighting,
Res.drawable.ic_light_mode,
AdminMessage.ModuleConfigType.AMBIENTLIGHTING_CONFIG.value,
),
DETECTION_SENSOR(
Res.string.detection_sensor,
- SettingsRoutes.DetectionSensor,
+ SettingsRoute.DetectionSensor,
Res.drawable.ic_sensors,
AdminMessage.ModuleConfigType.DETECTIONSENSOR_CONFIG.value,
),
PAXCOUNTER(
Res.string.paxcounter,
- SettingsRoutes.Paxcounter,
+ SettingsRoute.Paxcounter,
Res.drawable.ic_perm_scan_wifi,
AdminMessage.ModuleConfigType.PAXCOUNTER_CONFIG.value,
),
STATUS_MESSAGE(
Res.string.status_message,
- SettingsRoutes.StatusMessage,
+ SettingsRoute.StatusMessage,
Res.drawable.ic_message,
AdminMessage.ModuleConfigType.STATUSMESSAGE_CONFIG.value,
isSupported = { it.supportsStatusMessage },
),
TRAFFIC_MANAGEMENT(
Res.string.traffic_management,
- SettingsRoutes.TrafficManagement,
+ SettingsRoute.TrafficManagement,
Res.drawable.ic_alt_route,
AdminMessage.ModuleConfigType.TRAFFICMANAGEMENT_CONFIG.value,
isSupported = { it.supportsTrafficManagementConfig },
),
TAK(
Res.string.tak,
- SettingsRoutes.TAK,
+ SettingsRoute.TAK,
Res.drawable.ic_people,
AdminMessage.ModuleConfigType.TAK_CONFIG.value,
isSupported = { it.supportsTakConfig },

diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt
index ac713ae7e7..1409f6bdf3 100644
--- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt
+++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt
@@ -26,9 +26,9 @@ import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import org.koin.compose.viewmodel.koinViewModel
-import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.navigation.NodesRoute
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.feature.settings.AboutScreen
import org.meshtastic.feature.settings.AdministrationScreen
import org.meshtastic.feature.settings.DeviceConfigurationScreen
@@ -74,10 +74,10 @@ fun getRadioConfigViewModel(backStack: NavBackStack<NavKey>): RadioConfigViewMod
val viewModel = koinViewModel<RadioConfigViewModel>()
val destNum =
remember(backStack.toList()) {
- backStack.lastOrNull { it is SettingsRoutes.Settings }?.let { (it as SettingsRoutes.Settings).destNum }
+ backStack.lastOrNull { it is SettingsRoute.Settings }?.let { (it as SettingsRoute.Settings).destNum }
?: backStack
- .lastOrNull { it is SettingsRoutes.SettingsGraph }
- ?.let { (it as SettingsRoutes.SettingsGraph).destNum }
+ .lastOrNull { it is SettingsRoute.SettingsGraph }
+ ?.let { (it as SettingsRoute.SettingsGraph).destNum }
}
SideEffect { viewModel.initDestNum(destNum) }
return viewModel
@@ -85,25 +85,25 @@ fun getRadioConfigViewModel(backStack: NavBackStack<NavKey>): RadioConfigViewMod
@Suppress("LongMethod", "CyclomaticComplexMethod")
fun EntryProviderScope<NavKey>.settingsGraph(backStack: NavBackStack<NavKey>) {
- entry<SettingsRoutes.SettingsGraph> {
+ entry<SettingsRoute.SettingsGraph> {
SettingsMainScreen(
settingsViewModel = koinViewModel(),
radioConfigViewModel = getRadioConfigViewModel(backStack),
- onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) },
+ onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) },
onNavigate = { backStack.add(it) },
)
}
- entry<SettingsRoutes.Settings> {
+ entry<SettingsRoute.Settings> {
SettingsMainScreen(
settingsViewModel = koinViewModel(),
radioConfigViewModel = getRadioConfigViewModel(backStack),
- onClickNodeChip = { backStack.add(NodesRoutes.NodeDetail(it)) },
+ onClickNodeChip = { backStack.add(NodesRoute.NodeDetail(it)) },
onNavigate = { backStack.add(it) },
)
}
- entry<SettingsRoutes.DeviceConfiguration> {
+ entry<SettingsRoute.DeviceConfiguration> {
DeviceConfigurationScreen(
viewModel = getRadioConfigViewModel(backStack),
onBack = { backStack.removeLastOrNull() },
@@ -111,7 +111,7 @@ fun EntryProviderScope<NavKey>.settingsGraph(backStack: NavBackStack<NavKey>) {
)
}
- entry<SettingsRoutes.ModuleConfiguration> {
+ entry<SettingsRoute.ModuleConfiguration> {
val settingsViewModel: SettingsViewModel = koinViewModel()
val excludedModulesUnlocked by settingsViewModel.excludedModulesUnlocked.collectAsStateWithLifecycle()
ModuleConfigurationScreen(
@@ -122,11 +122,11 @@ fun EntryProviderScope<NavKey>.settingsGraph(backStack: NavBackStack<NavKey>) {
)
}
- entry<SettingsRoutes.Administration> {
+ entry<SettingsRoute.Administration> {
AdministrationScreen(viewModel = getRadioConfigViewModel(backStack), onBack = { backStack.removeLastOrNull() })
}
- entry<SettingsRoutes.CleanNodeDb> {
+ entry<SettingsRoute.CleanNodeDb> {
val viewModel: CleanNodeDatabaseViewModel = koinViewModel()
CleanNodeDatabaseScreen(viewModel = viewModel)
}
@@ -185,16 +185,16 @@ fun EntryProviderScope<NavKey>.settingsGraph(backStack: NavBackStack<NavKey>) {
}
}
- entry<SettingsRoutes.DebugPanel> {
+ entry<SettingsRoute.DebugPanel> {
val viewModel: DebugViewModel = koinViewModel()
DebugScreen(viewModel = viewModel, onNavigateUp = { backStack.removeLastOrNull() })
}
- entry<SettingsRoutes.About> {
+ entry<SettingsRoute.About> {
AboutScreen(onNavigateUp = { backStack.removeLastOrNull() }, jsonProvider = { getAboutLibrariesJson() })
}
- entry<SettingsRoutes.FilterSettings> {
+ entry<SettingsRoute.FilterSettings> {
val viewModel: FilterSettingsViewModel = koinViewModel()
FilterSettingsScreen(viewModel = viewModel, onBack = { backStack.removeLastOrNull() })
}

diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt
index 4fb2fa41af..7688953271 100644
--- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt
+++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt
@@ -28,9 +28,9 @@ import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.resources.vectorResource
-import org.meshtastic.core.navigation.FirmwareRoutes
+import org.meshtastic.core.navigation.FirmwareRoute
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.administration
import org.meshtastic.core.resources.advanced_title
@@ -125,7 +125,7 @@ private fun DeviceConfigSection(isManaged: Boolean, enabled: Boolean, onNavigate
trailingIcon = MeshtasticIcons.KeyboardArrowRight,
enabled = enabled,
) {
- onNavigate(SettingsRoutes.DeviceConfiguration)
+ onNavigate(SettingsRoute.DeviceConfiguration)
}
}
}
@@ -142,7 +142,7 @@ private fun ModuleSettingsSection(isManaged: Boolean, enabled: Boolean, onNaviga
trailingIcon = MeshtasticIcons.KeyboardArrowRight,
enabled = enabled,
) {
- onNavigate(SettingsRoutes.ModuleConfiguration)
+ onNavigate(SettingsRoute.ModuleConfiguration)
}
}
}
@@ -181,7 +181,7 @@ private fun AdministrationSection(enabled: Boolean, onNavigate: (Route) -> Unit)
trailingIconTint = MaterialTheme.colorScheme.error,
enabled = enabled,
) {
- onNavigate(SettingsRoutes.Administration)
+ onNavigate(SettingsRoute.Administration)
}
}
}
@@ -198,7 +198,7 @@ private fun AdvancedSection(isManaged: Boolean, isOtaCapable: Boolean, enabled:
text = stringResource(Res.string.firmware_update_title),
leadingIcon = MeshtasticIcons.SystemUpdate,
enabled = enabled,
- onClick = { onNavigate(FirmwareRoutes.FirmwareUpdate) },
+ onClick = { onNavigate(FirmwareRoute.FirmwareUpdate) },
)
}
@@ -206,14 +206,14 @@ private fun AdvancedSection(isManaged: Boolean, isOtaCapable: Boolean, enabled:
text = stringResource(Res.string.clean_node_database_title),
leadingIcon = MeshtasticIcons.CleaningServices,
enabled = enabled,
- onClick = { onNavigate(SettingsRoutes.CleanNodeDb) },
+ onClick = { onNavigate(SettingsRoute.CleanNodeDb) },
)
ListItem(
text = stringResource(Res.string.debug_panel),
leadingIcon = MeshtasticIcons.BugReport,
enabled = enabled,
- onClick = { onNavigate(SettingsRoutes.DebugPanel) },
+ onClick = { onNavigate(SettingsRoute.DebugPanel) },
)
}
}

diff --git a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt
index 9966ca24e6..f73b6b731f 100644
--- a/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt
+++ b/feature/settings/src/commonMain/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelsNavigation.kt
@@ -20,12 +20,12 @@ import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import org.koin.compose.viewmodel.koinViewModel
-import org.meshtastic.core.navigation.ChannelsRoutes
+import org.meshtastic.core.navigation.ChannelsRoute
import org.meshtastic.feature.settings.radio.RadioConfigViewModel
-/** Navigation graph for for the top level ChannelScreen - [ChannelsRoutes.Channels]. */
+/** Navigation graph for for the top level ChannelScreen - [ChannelsRoute.Channels]. */
fun EntryProviderScope<NavKey>.channelsGraph(backStack: NavBackStack<NavKey>) {
- entry<ChannelsRoutes.ChannelsGraph> {
+ entry<ChannelsRoute.ChannelsGraph> {
ChannelScreen(
radioConfigViewModel = koinViewModel<RadioConfigViewModel>(),
onNavigate = { route -> backStack.add(route) },
@@ -33,7 +33,7 @@ fun EntryProviderScope<NavKey>.channelsGraph(backStack: NavBackStack<NavKey>) {
)
}
- entry<ChannelsRoutes.Channels> {
+ entry<ChannelsRoute.Channels> {
ChannelScreen(
radioConfigViewModel = koinViewModel<RadioConfigViewModel>(),
onNavigate = { route -> backStack.add(route) },

diff --git a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt
index 21cb3b09f0..3ebe556b00 100644
--- a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt
+++ b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/DesktopSettingsScreen.kt
@@ -39,8 +39,8 @@ import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.database.DatabaseConstants
import org.meshtastic.core.navigation.Route
-import org.meshtastic.core.navigation.SettingsRoutes
-import org.meshtastic.core.navigation.WifiProvisionRoutes
+import org.meshtastic.core.navigation.SettingsRoute
+import org.meshtastic.core.navigation.WifiProvisionRoute
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.acknowledgements
import org.meshtastic.core.resources.app_settings
@@ -202,7 +202,7 @@ fun DesktopSettingsScreen(
ExpressiveSection(title = stringResource(Res.string.wifi_devices)) {
ListItem(text = stringResource(Res.string.wifi_devices), leadingIcon = MeshtasticIcons.Wifi) {
- onNavigate(WifiProvisionRoutes.WifiProvision())
+ onNavigate(WifiProvisionRoute.WifiProvision())
}
}
@@ -219,7 +219,7 @@ fun DesktopSettingsScreen(
appVersionName = settingsViewModel.appVersionName,
excludedModulesUnlocked = excludedModulesUnlocked,
onUnlockExcludedModules = { settingsViewModel.unlockExcludedModules() },
- onNavigateToAbout = { onNavigate(SettingsRoutes.About) },
+ onNavigateToAbout = { onNavigate(SettingsRoute.About) },
)
}
}

diff --git a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt
index 4b9cf369d4..0a35599f5d 100644
--- a/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt
+++ b/feature/settings/src/jvmMain/kotlin/org/meshtastic/feature/settings/navigation/AboutLibrariesLoader.kt
@@ -16,7 +16,7 @@
*/
package org.meshtastic.feature.settings.navigation
-import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.navigation.SettingsRoute
actual fun getAboutLibrariesJson(): String =
- SettingsRoutes::class.java.getResource("/aboutlibraries.json")?.readText() ?: ""
+ SettingsRoute::class.java.getResource("/aboutlibraries.json")?.readText() ?: ""

diff --git a/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt b/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt
index 472f1effe6..ea30112c7a 100644
--- a/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt
+++ b/feature/wifi-provision/src/commonMain/kotlin/org/meshtastic/feature/wifiprovision/navigation/WifiProvisionNavigation.kt
@@ -19,21 +19,21 @@ package org.meshtastic.feature.wifiprovision.navigation
import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
-import org.meshtastic.core.navigation.WifiProvisionRoutes
+import org.meshtastic.core.navigation.WifiProvisionRoute
import org.meshtastic.feature.wifiprovision.ui.WifiProvisionScreen
/**
* Registers the WiFi provisioning graph entries into the host navigation provider.
*
- * Both the graph sentinel ([WifiProvisionRoutes.WifiProvisionGraph]) and the primary screen
- * ([WifiProvisionRoutes.WifiProvision]) navigate to the same composable so that the feature can be reached via either a
+ * Both the graph sentinel ([WifiProvisionRoute.WifiProvisionGraph]) and the primary screen
+ * ([WifiProvisionRoute.WifiProvision]) navigate to the same composable so that the feature can be reached via either a
* top-level push or a deep-link graph push.
*/
fun EntryProviderScope<NavKey>.wifiProvisionGraph(backStack: NavBackStack<NavKey>) {
- entry<WifiProvisionRoutes.WifiProvisionGraph> {
+ entry<WifiProvisionRoute.WifiProvisionGraph> {
WifiProvisionScreen(onNavigateUp = { backStack.removeLastOrNull() })
}
- entry<WifiProvisionRoutes.WifiProvision> { key ->
+ entry<WifiProvisionRoute.WifiProvision> { key ->
WifiProvisionScreen(onNavigateUp = { backStack.removeLastOrNull() }, address = key.address)
}
}

Served by rngit 1.5.0 - Generated in 0.48s